#include "gpio.h"
#include "stm32f10x_gpio.h"
#include "time.h"
#include "oledfont.h"
#include "usart.h"
#include "delay.h"
uint16_t Rotating1[4] = {0x0120U , 0X0060U , 0x00C0U, 0X0180U };
void GpioInit(void)
{
    GPIO_InitTypeDef	GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin=ADC1_IN4|ADC1_IN5|ADC1_IN6|ADC1_IN7;		//光敏A0	烟雾A0 	雨水A0
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=KEY1|KEY2|KEY3|KEY4;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=LED_PIN;			//LED的初始化,PC13
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOC,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=voice;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=I2C2_SCL|I2C2_SDA;			//PB10 PB11
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=Light|Smoke|Rain|hot;						//PB4	PB9光敏D0	PB9烟雾D0	PB12雨水D0	PB13温湿度
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=Step_A|Step_B|Step_C|Step_D; 	//PB5 PB6 PB7 PB8	步进电机
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=buzzer;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_SetBits(GPIOB,GPIO_Pin_14);
	GPIO_ResetBits(GPIOC,GPIO_Pin_13);
	GPIO_ResetBits(GPIOB,Step_A);
	GPIO_ResetBits(GPIOB,Step_B);
	GPIO_ResetBits(GPIOB,Step_C);
	GPIO_ResetBits(GPIOB,Step_D);
}
//没有超过阈值，输出1
uint8_t get_light_level(void)
{
	return GPIO_ReadInputDataBit(GPIOB,Light);
}
//没有超过阈值，输出1
uint8_t get_smoke_level(void)
{
	return GPIO_ReadInputDataBit(GPIOB,Smoke);
}
//没有雨水，输出1
uint8_t get_rain_level(void)
{
	return GPIO_ReadInputDataBit(GPIOB,Rain);
}
//有人靠近输出高电平
uint8_t get_hot_level(void)
{
	return GPIO_ReadInputDataBit(GPIOB,hot);
}
uint8_t get_voice_level(void){
	return GPIO_ReadInputDataBit(GPIOA,voice); 
}
uint8_t key_scan(void)
{
	static uint8_t key_up=1;	  
	if(key_up&&(KEY1_read==0||KEY2_read==0||KEY3_read==0||KEY4_read==0))
	{
		Tim3_delay_ms(10);
		key_up=0;
		if(KEY1_read==0)return 1;
		else if(KEY2_read==0)return 2;
		else if(KEY3_read==0)return 3;
		else if(KEY4_read==0)return 4;
	}else if(KEY1_read==1&&KEY2_read==1&&KEY3_read==1&&KEY4_read==1)key_up=1; 	    
 	return 0;
}
void step_on(void)
{
	int Rot=0;
	for(uint16_t i=0;i<1024;i++)
	{
		Rot++;
		Rot = CLIP_ROT(Rot,0,3);
		GPIO_WriteBit(GPIOB,Rotating1[Rot],1);
		GPIO_WriteBit(GPIOB,0x01f0-Rotating1[Rot],0);
		Tim3_delay_ms(5);
	}
}
void step_off(void)
{
	int Rot=4;
	for(uint16_t i=0;i<1024;i++)
	{
		Rot--;
		Rot = CLIP_ROT(Rot,0,3);
		GPIO_WriteBit(GPIOB,Rotating1[Rot],1);
		GPIO_WriteBit(GPIOB,0x01f0-Rotating1[Rot],0);
		Tim3_delay_ms(5);
	}
}

void buzzer_off(void)
{
	GPIO_SetBits(GPIOB,buzzer);
}
void buzzer_on(void)
{
	GPIO_ResetBits(GPIOB,buzzer);
}

//void Dht11_OutputMode(void)
//{
//	GPIO_InitTypeDef	GPIO_InitStructure;
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
//	
//	GPIO_InitStructure.GPIO_Mode=tem_hum;
//	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
//	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//	GPIO_Init(GPIOB,&GPIO_InitStructure);
//	GPIO_SetBits(GPIOB,tem_hum);
//	Tim3_delay_ms(10);
//}
//void Dht11_InputMode(void)
//{
//	GPIO_InitTypeDef	GPIO_InitStructure;
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
//	
//	GPIO_InitStructure.GPIO_Mode=tem_hum;
//	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
//	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//	GPIO_Init(GPIOB,&GPIO_InitStructure);
//}
//uint8_t DHT11_ReadByte(void)
//{
//	u8 bit_value;
//	u8 value=0;
//	u8 count;
//	for(count=0;count<8;count++)
//	{
//		if(!PBin(13))
//		{
//			while(!PBin(13));
//			Tim3_delay_us(50);
//			if(PBin(13))
//			bit_value = 1;
//			else
//			bit_value = 0;
//		}
//		value <<= 1;
//		value |=  bit_value;
//		while(PBin(13));
//	}              
//	return value;
//}
//void DHT11_Read(uint8_t *pTemp, uint8_t *pHum)
//{
//	uint16_t i=0;
//	Dht11_OutputMode();
//	PBout(13) = 0;	
//	Tim3_delay_ms(23); 
//	PBout(13) = 1;
//	Tim3_delay_us(25);
//	Dht11_InputMode();
//	while(PBin(13)){
//		Tim3_delay_us(1);
//		i++;
//		if(i>8000){return ;}
//	}
//	uint8_t buf[6]={0};
//	sprintf((char*)buf,"ok\r\n");
//	printf2(buf);
//	if(!PBin(13))
//	{
//        while(!PBin(13));
//        while(PBin(13)); 
//        *pHum = DHT11_ReadByte();
//        DHT11_ReadByte();       
//        *pTemp = DHT11_ReadByte();
//        DHT11_ReadByte();  
//        DHT11_ReadByte();
//        PBout(13) = 1;
//   }
//}

u8 DHT11_Init(void)
{	 
 	GPIO_InitTypeDef  GPIO_InitStructure;
 	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	
	
 	GPIO_InitStructure.GPIO_Pin = tem_hum;			
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 	
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);			
 	GPIO_SetBits(GPIOB,GPIO_Pin_13);						
			    
	DHT11_Rst(); 
	return DHT11_Check();
} 
void DHT11_Rst(void)	   
{                 
	DHT11_IO_OUT(); 	
    DHT11_DQ_OUT=0; 	
    delay_ms(20);    
    DHT11_DQ_OUT=1; 
	delay_us(30);
}
u8 DHT11_Check(void) 	   
{   
	u8 retry=0;
	DHT11_IO_IN();
    while (DHT11_DQ_IN&&retry<100)
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=100)return 1;
	else retry=0;
    while (!DHT11_DQ_IN&&retry<100)
	{
		retry++;
		delay_us(1);
	};
	if(retry>=100)return 1;	    
	return 0;
}
u8 DHT11_Read_Bit(void) 			 
{
 	u8 retry=0;
	while(DHT11_DQ_IN&&retry<100)
	{
		retry++;
		delay_us(1);
	}
	retry=0;
	while(!DHT11_DQ_IN&&retry<100)
	{
		retry++;
		delay_us(1);
	}
	delay_us(40);
	if(DHT11_DQ_IN)return 1;
	else return 0;		   
}

u8 DHT11_Read_Byte(void)    
{        
    u8 i,dat;
    dat=0;
	for (i=0;i<8;i++) 
	{
   		dat<<=1; 
	    dat|=DHT11_Read_Bit();
    }						    
    return dat;
}

u8 DHT11_Read_Data(u8 *temp,u8 *humi)    
{        
 	u8 buf[5];
	u8 i;
	DHT11_Rst();
	if(DHT11_Check()==0)
	{
		for(i=0;i<5;i++)
		{
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			*humi=buf[0];
			*temp=buf[2];
		}
	}else return 1;
	return 0;	    
}
void SDA_OUT(void)
{
	GPIO_InitTypeDef	GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin=I2C2_SDA;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}
void SDA_IN(void)
{
	GPIO_InitTypeDef	GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin=I2C2_SDA;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}
void IIC_Start(void)
{
	SDA_OUT();     
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	Tim3_delay_us(4);
 	IIC_SDA=0;
	Tim3_delay_us(4);
	IIC_SCL=0;
}	  

void IIC_Stop(void)
{
	SDA_OUT();//sdaÏßÊä³ö
	IIC_SCL=0;
	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 	Tim3_delay_us(4);
	IIC_SCL=1; 
	IIC_SDA=1;
	Tim3_delay_us(4);							   	
}

u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();     
	IIC_SDA=1;Tim3_delay_us(1);	   
	IIC_SCL=1;Tim3_delay_us(1);	 
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL=0;
	return 0;  
} 

void IIC_Ack(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=0;
	Tim3_delay_us(2);
	IIC_SCL=1;
	Tim3_delay_us(2);
	IIC_SCL=0;
}

void IIC_NAck(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=1;
	Tim3_delay_us(2);
	IIC_SCL=1;
	Tim3_delay_us(2);
	IIC_SCL=0;
}					 				     
	  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	    
    IIC_SCL=0;
    for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7;
        txd<<=1; 	  
		Tim3_delay_us(2);  
		IIC_SCL=1;
		Tim3_delay_us(2); 
		IIC_SCL=0;	
		Tim3_delay_us(2);
    }	 
} 	    

u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();
    for(i=0;i<8;i++ )
	{
        IIC_SCL=0; 
        Tim3_delay_us(2);
		IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
		Tim3_delay_us(1); 
    }					 
    if (!ack)
        IIC_NAck();
    else
        IIC_Ack(); 
    return receive;
}

void WriteCmd(unsigned char I2C_Command)
{
	 IIC_Start();
     IIC_Send_Byte(OLED_ADDRESS);
     IIC_Wait_Ack();
     IIC_Send_Byte(OLED_cmd_address);
     IIC_Wait_Ack();
     IIC_Send_Byte(I2C_Command);
     IIC_Wait_Ack();
     IIC_Stop();
}

void WriteDat(unsigned char I2C_Data)
{
	 IIC_Start();
     IIC_Send_Byte(OLED_ADDRESS);
     IIC_Wait_Ack();
     IIC_Send_Byte(OLED_data_address);
     IIC_Wait_Ack();
     IIC_Send_Byte(I2C_Data);
     IIC_Wait_Ack();
     IIC_Stop();
}
void OLED_Init(void)
{
	Tim3_delay_ms(50); 
	Tim3_delay_ms(50); 
    WriteCmd(0xAE); //display off
    WriteCmd(0x20); //Set Memory Addressing Mode    
    WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
    WriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
    WriteCmd(0xc8); //Set COM Output Scan Direction
    WriteCmd(0x00); //---set low column address
    WriteCmd(0x10); //---set high column address
    WriteCmd(0x40); //--set start line address
    WriteCmd(0x81); //--set contrast control register
    WriteCmd(0xff); //ÁÁ¶Èµ÷½Ú 0x00~0xff
    WriteCmd(0xa1); //--set segment re-map 0 to 127
    WriteCmd(0xa6); //--set normal display
    WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
    WriteCmd(0x3F); //
    WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
    WriteCmd(0xd3); //-set display offset
    WriteCmd(0x00); //-not offset
    WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
    WriteCmd(0xf0); //--set divide ratio
    WriteCmd(0xd9); //--set pre-charge period
    WriteCmd(0x22); //
    WriteCmd(0xda); //--set com pins hardware configuration
    WriteCmd(0x12);
    WriteCmd(0xdb); //--set vcomh
    WriteCmd(0x20); //0x20,0.77xVcc
    WriteCmd(0x8d); //--set DC-DC enable
    WriteCmd(0x14); //
    WriteCmd(0xaf); //--turn on oled panel
}
void OLED_Fill(unsigned char fill_Data)
{
	unsigned char m,n;
	for(m=0;m<8;m++)
	{
		WriteCmd(0xb0+m);		//page0-page1
		WriteCmd(0x00);		//low column start address
		WriteCmd(0x10);		//high column start address
		for(n=0;n<128;n++)
			{
				WriteDat(fill_Data);
			}
	}
}

void OLED_CLS(void)
{
	OLED_Fill(0x00);
}
void OLED_SetPos(unsigned char x, unsigned char y) 
{ 
	WriteCmd(0xb0+y);
	WriteCmd(((x&0xf0)>>4)|0x10);
	WriteCmd((x&0x0f)|0x01);
}
void OLED_ShowStr(unsigned char x, unsigned char y, uint8_t ch[])
{
	unsigned char c = 0,i = 0,j = 0;
	while(ch[j] != '\0')
	{
		if(ch[j]<0x80)
		{
			c = ch[j] - 32;
			if(x > 120)
			{
				x = 0;
				y++;
			}
			OLED_SetPos(x,y);
			for(i=0;i<8;i++)
			WriteDat(F8X16[c*16+i]);
			OLED_SetPos(x,y+1);
			for(i=0;i<8;i++)
			WriteDat(F8X16[c*16+i+8]);
			x += 8;
			j++;
		}else{
			uint8_t num=sizeof(F16X16)/sizeof(struct f16x16);
			for(uint8_t n=0;n<num;n++)
			{
				if(F16X16[n].idex[0]==ch[j]&&F16X16[n].idex[1]==ch[j+1]&&F16X16[n].idex[2]==ch[j+2])
				{
					if(x > 120)
					{
						x = 0;
						y++;
					}
					OLED_SetPos(x,y);
					for(i=0;i<16;i++)
					WriteDat(F16X16[n].buf[i]);
					OLED_SetPos(x,y+1);
					for(i=16;i<32;i++)
					WriteDat(F16X16[n].buf[i]);
					x +=16;
					j+=3;
				}
			}
		}
	}
}


